using System;
using System.Collections;
using System.Text;

using Qiang.Topology.Geometries;
using Qiang.Topology.GeometriesGraph;
using Qiang.Topology.Algorithm;

namespace Qiang.Topology.Operation
{
    /// <summary>
    /// The base class for operations that require {GeometryGraph)s.
    /// </summary>
    public class GeometryGraphOperation
    {        
        protected LineIntersector li = new RobustLineIntersector();
        protected PrecisionModel resultPrecisionModel;

        /**
        * The operation args into an array so they can be accessed by index
        */
        protected GeometryGraph[] arg;  // the arg(s) of the operation

        /// <summary>
        /// 
        /// </summary>
        /// <param name="g0"></param>
        /// <param name="g1"></param>
        public GeometryGraphOperation(IGeometry g0, IGeometry g1)
        {
            // use the most precise model for the result
            if (g0.PrecisionModel.CompareTo(g1.PrecisionModel) >= 0)
                 ComputationPrecision = g0.PrecisionModel;
            else ComputationPrecision = g1.PrecisionModel;

            arg = new GeometryGraph[2];
            arg[0] = new GeometryGraph(0, g0);
            arg[1] = new GeometryGraph(1, g1);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="g0"></param>
        public GeometryGraphOperation(Geometry g0) 
        {
            ComputationPrecision = g0.PrecisionModel;

            arg = new GeometryGraph[1];
            arg[0] = new GeometryGraph(0, g0);;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public virtual IGeometry GetArgGeometry(int i)
        {
            return arg[i].Geometry; 
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual PrecisionModel ComputationPrecision
        {
            get
            {
                return resultPrecisionModel;
            }
            set
            {
                resultPrecisionModel = value;
                li.PrecisionModel = resultPrecisionModel;
            }
        }
    }
}
